
/*

Design Pattern Automation Toolkit.
Application to create applications with emphasis on Design patterns.
And support for round trip engineering.
Copyright (C) 2004 Vineeth Neelakant. nvineeth@gmail.com

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/
using System;
using BusinessLayer;
using InfoClasses;
using dpatoolkit.UILayer;
using System.Data;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Reflection;
using DesignPatternDefinitions;

namespace dpatoolkit.UILayer
{
    /// <summary>
    /// Summary description for CodeGenPluginForm.
    /// </summary>
    public class CodeGenPluginForm : System.Windows.Forms.Form
    {
        private System.Data.DataSet codeGenDataSet;
        private System.Windows.Forms.GroupBox groupBox2;
        private System.Windows.Forms.Button AddPluginButton;
        private System.Windows.Forms.GroupBox groupBox1;
        private System.Windows.Forms.ListBox plugInListBox;
        private System.Data.DataTable dataTable1;
        private System.Data.DataColumn dataColumn1;
        private System.Windows.Forms.DataGrid dataGrid1;
        private System.Windows.Forms.Button RemovePlugInButton;
        private System.Windows.Forms.Button cancelButton;
        private System.Windows.Forms.Button okButton;
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.Container components = null;

        private ArrayList codeGenerators = new ArrayList();

        public CodeGenPluginForm()
        {
            //
            // Required for Windows Form Designer support
            //
            InitializeComponent();
            //this.Paint+=new PaintEventHandler(FormPainter.Paint);
            this.LoadSnapIns();
        }

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (components != null)
                {
                    components.Dispose();
                }
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.okButton = new System.Windows.Forms.Button();
            this.cancelButton = new System.Windows.Forms.Button();
            this.RemovePlugInButton = new System.Windows.Forms.Button();
            this.dataGrid1 = new System.Windows.Forms.DataGrid();
            this.dataTable1 = new System.Data.DataTable();
            this.dataColumn1 = new System.Data.DataColumn();
            this.plugInListBox = new System.Windows.Forms.ListBox();
            this.groupBox1 = new System.Windows.Forms.GroupBox();
            this.AddPluginButton = new System.Windows.Forms.Button();
            this.groupBox2 = new System.Windows.Forms.GroupBox();
            this.codeGenDataSet = new System.Data.DataSet();
            ((System.ComponentModel.ISupportInitialize)(this.dataGrid1)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.dataTable1)).BeginInit();
            this.groupBox1.SuspendLayout();
            this.groupBox2.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)(this.codeGenDataSet)).BeginInit();
            this.SuspendLayout();
            // 
            // okButton
            // 
            this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK;
            this.okButton.FlatStyle = System.Windows.Forms.FlatStyle.System;
            this.okButton.Location = new System.Drawing.Point(368, 280);
            this.okButton.Name = "okButton";
            this.okButton.TabIndex = 3;
            this.okButton.Text = "&OK";
            this.okButton.Click += new System.EventHandler(this.okButton_Click);
            // 
            // cancelButton
            // 
            this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
            this.cancelButton.FlatStyle = System.Windows.Forms.FlatStyle.System;
            this.cancelButton.Location = new System.Drawing.Point(472, 280);
            this.cancelButton.Name = "cancelButton";
            this.cancelButton.TabIndex = 4;
            this.cancelButton.Text = "&Cancel";
            this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click);
            // 
            // RemovePlugInButton
            // 
            this.RemovePlugInButton.FlatStyle = System.Windows.Forms.FlatStyle.System;
            this.RemovePlugInButton.Location = new System.Drawing.Point(464, 48);
            this.RemovePlugInButton.Name = "RemovePlugInButton";
            this.RemovePlugInButton.Size = new System.Drawing.Size(96, 23);
            this.RemovePlugInButton.TabIndex = 2;
            this.RemovePlugInButton.Text = "&Remove PlugIn";
            this.RemovePlugInButton.Click += new System.EventHandler(this.RemovePlugInButton_Click);
            // 
            // dataGrid1
            // 
            this.dataGrid1.AllowNavigation = false;
            this.dataGrid1.AlternatingBackColor = System.Drawing.Color.Lavender;
            this.dataGrid1.BackColor = System.Drawing.Color.WhiteSmoke;
            this.dataGrid1.BackgroundColor = System.Drawing.Color.LightGray;
            this.dataGrid1.BorderStyle = System.Windows.Forms.BorderStyle.None;
            this.dataGrid1.CaptionBackColor = System.Drawing.Color.LightSteelBlue;
            this.dataGrid1.CaptionForeColor = System.Drawing.Color.MidnightBlue;
            this.dataGrid1.DataMember = "";
            this.dataGrid1.DataSource = this.dataTable1;
            this.dataGrid1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.dataGrid1.FlatMode = true;
            this.dataGrid1.Font = new System.Drawing.Font("Tahoma", 8F);
            this.dataGrid1.ForeColor = System.Drawing.Color.MidnightBlue;
            this.dataGrid1.GridLineColor = System.Drawing.Color.Gainsboro;
            this.dataGrid1.GridLineStyle = System.Windows.Forms.DataGridLineStyle.None;
            this.dataGrid1.HeaderBackColor = System.Drawing.Color.MidnightBlue;
            this.dataGrid1.HeaderFont = new System.Drawing.Font("Tahoma", 8F, System.Drawing.FontStyle.Bold);
            this.dataGrid1.HeaderForeColor = System.Drawing.Color.WhiteSmoke;
            this.dataGrid1.LinkColor = System.Drawing.Color.Teal;
            this.dataGrid1.Location = new System.Drawing.Point(3, 16);
            this.dataGrid1.Name = "dataGrid1";
            this.dataGrid1.ParentRowsBackColor = System.Drawing.Color.Gainsboro;
            this.dataGrid1.ParentRowsForeColor = System.Drawing.Color.MidnightBlue;
            this.dataGrid1.PreferredColumnWidth = 500;
            this.dataGrid1.ReadOnly = true;
            this.dataGrid1.SelectionBackColor = System.Drawing.Color.CadetBlue;
            this.dataGrid1.SelectionForeColor = System.Drawing.Color.WhiteSmoke;
            this.dataGrid1.Size = new System.Drawing.Size(434, 85);
            this.dataGrid1.TabIndex = 0;
            // 
            // dataTable1
            // 
            this.dataTable1.Columns.AddRange(new System.Data.DataColumn[] {
												      this.dataColumn1});
            this.dataTable1.Constraints.AddRange(new System.Data.Constraint[] {
													  new System.Data.UniqueConstraint("Constraint1", new string[] {
																					       "PluginPath"}, true)});
            this.dataTable1.PrimaryKey = new System.Data.DataColumn[] {
												  this.dataColumn1};
            this.dataTable1.TableName = "Plugins";
            // 
            // dataColumn1
            // 
            this.dataColumn1.AllowDBNull = false;
            this.dataColumn1.ColumnName = "PluginPath";
            // 
            // plugInListBox
            // 
            this.plugInListBox.Dock = System.Windows.Forms.DockStyle.Fill;
            this.plugInListBox.Location = new System.Drawing.Point(3, 16);
            this.plugInListBox.Name = "plugInListBox";
            this.plugInListBox.Size = new System.Drawing.Size(514, 121);
            this.plugInListBox.TabIndex = 0;
            // 
            // groupBox1
            // 
            this.groupBox1.Controls.Add(this.plugInListBox);
            this.groupBox1.Location = new System.Drawing.Point(16, 128);
            this.groupBox1.Name = "groupBox1";
            this.groupBox1.Size = new System.Drawing.Size(520, 144);
            this.groupBox1.TabIndex = 5;
            this.groupBox1.TabStop = false;
            this.groupBox1.Text = "Avaliable Code Generator Classes";
            // 
            // AddPluginButton
            // 
            this.AddPluginButton.FlatStyle = System.Windows.Forms.FlatStyle.System;
            this.AddPluginButton.Location = new System.Drawing.Point(464, 16);
            this.AddPluginButton.Name = "AddPluginButton";
            this.AddPluginButton.Size = new System.Drawing.Size(88, 23);
            this.AddPluginButton.TabIndex = 1;
            this.AddPluginButton.Text = "&Add plugin";
            this.AddPluginButton.Click += new System.EventHandler(this.AddPluginButton_Click);
            // 
            // groupBox2
            // 
            this.groupBox2.Controls.Add(this.dataGrid1);
            this.groupBox2.Location = new System.Drawing.Point(16, 16);
            this.groupBox2.Name = "groupBox2";
            this.groupBox2.Size = new System.Drawing.Size(440, 104);
            this.groupBox2.TabIndex = 6;
            this.groupBox2.TabStop = false;
            this.groupBox2.Text = "Loaded Plugins";
            // 
            // codeGenDataSet
            // 
            this.codeGenDataSet.CaseSensitive = true;
            this.codeGenDataSet.DataSetName = "CodeGenerationPlugins";
            this.codeGenDataSet.Locale = new System.Globalization.CultureInfo("en-US");
            this.codeGenDataSet.Tables.AddRange(new System.Data.DataTable[] {
													this.dataTable1});
            // 
            // CodeGenPluginForm
            // 
            this.AcceptButton = this.okButton;
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.CancelButton = this.cancelButton;
            this.ClientSize = new System.Drawing.Size(568, 318);
            this.Controls.Add(this.groupBox2);
            this.Controls.Add(this.groupBox1);
            this.Controls.Add(this.cancelButton);
            this.Controls.Add(this.okButton);
            this.Controls.Add(this.RemovePlugInButton);
            this.Controls.Add(this.AddPluginButton);
            this.Name = "CodeGenPluginForm";
            this.Text = "Code Generators";
            this.Closing += new System.ComponentModel.CancelEventHandler(this.CodeGenPluginFormClosing);
            ((System.ComponentModel.ISupportInitialize)(this.dataGrid1)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.dataTable1)).EndInit();
            this.groupBox1.ResumeLayout(false);
            this.groupBox2.ResumeLayout(false);
            ((System.ComponentModel.ISupportInitialize)(this.codeGenDataSet)).EndInit();
            this.ResumeLayout(false);

        }
        #endregion

        public IDPACodeGenerator CodeGenerator
        {

            get
            {
                if (this.DialogResult == DialogResult.Cancel)
                    return null;

                int index = 0;
                if (this.plugInListBox.SelectedIndex >= 0)
                {
                    index = this.plugInListBox.SelectedIndex;
                    return this.codeGenerators[index] as IDPACodeGenerator;
                }
                return null;
            }
        }


        private static string PluginTable = "Plugins";
        private void LoadSnapIns()
        {
            // here we read the config file in the same directory.
            DataTable table;
            try
            {
                try
                {
                    this.codeGenDataSet.ReadXml(dpatoolkit.GlobalSettings.CodeGenConfigFile);
                }
                catch
                {
                    ErrorMessage.Show("Error while reading the configuration file for code generation \n plug ins", "Error");
                }
                table = this.codeGenDataSet.Tables[PluginTable];
                string autoAddPath = dpatoolkit.GlobalSettings.DefaultCodeGenerationPlugin;
                if (System.IO.File.Exists(autoAddPath) && table.Rows.Find(autoAddPath) == null)
                {
                    DataRow nrow = table.NewRow();
                    nrow[0] = autoAddPath;
                    table.Rows.Add(nrow);
                }
                foreach (DataRow row in table.Rows)
                {
                    this.TryToUseSnapIn((string)row[0]);
                }
            }
            catch
            {
                ErrorMessage.Show("Error while reading the configuration file for code generation \n plug ins", "Error");
            }

        }
        private void AddPluginButton_Click(object sender, System.EventArgs e)
        {

            OpenFileDialog myOpenFileDialog = new OpenFileDialog();
            if (myOpenFileDialog.ShowDialog() == DialogResult.OK)
            {
                //add it to the table.
                string pathToAsm = myOpenFileDialog.FileName;
                DataRow row = this.codeGenDataSet.Tables[PluginTable].NewRow();
                row[0] = pathToAsm;
                try
                {
                    this.codeGenDataSet.Tables[PluginTable].Rows.Add(row);
                }
                catch
                {
                    ErrorMessage.Show("This plugin has already been added", "error");
                    return;

                }

                if (TryToUseSnapIn(pathToAsm) == false)
                {
                    ErrorMessage.Show("This is not a valid snap-In", "Error while loading snapIn");
                    this.codeGenDataSet.Tables[PluginTable].Rows.Remove(row);

                    return;
                }
                else
                {
                    this.plugInListBox.SelectedIndex = 0;
                }

            }
        }

        private void RemovePlugInButton_Click(object sender, System.EventArgs e)
        {

        }

        private bool TryToUseSnapIn(string path)
        {
            // Load the asm.
            bool foundSnapIn = false;
            Assembly theSnapInAsm;
            try
            {
                theSnapInAsm = Assembly.LoadFrom(path);
            }
            catch
            {
                ErrorMessage.Show("Error while reading the assembly:" + path, "Error");
                return false;
            }

            // Get all types in assembly.
            Type[] theTypes = theSnapInAsm.GetTypes();

            // Get custom attributes for each type, and 
            // see if one of them is [Snappable] 
            for (int i = 0; i < theTypes.Length; i++)
            {
                object[] theAtts = theTypes[i].GetCustomAttributes(false);

                for (int j = 0; j < theAtts.Length; j++)
                {
                    if (theAtts[j] is CodeGenerationLanguage)
                    {
                        CodeGenerationLanguage lang = theAtts[j] as CodeGenerationLanguage;
                        foundSnapIn = true;
                        object o = theSnapInAsm.CreateInstance(theTypes[i].FullName);
                        IDPACodeGenerator codeGen;
                        codeGen = o as IDPACodeGenerator;

                        if (codeGen != null)
                        {
                            //							if( !this.silent)	
                            //							MessageBox.Show(this,"The following plug in was found\n Language:"+lang.Language+"\n"+" Provider:"+lang.Provider,
                            //								"Plugin found",MessageBoxButtons.OK,MessageBoxIcon.Information);
                            this.plugInListBox.Items.Add(lang.Language + "," + lang.Provider);
                            this.codeGenerators.Add(codeGen);
                        }
                    }
                }
            }
            theSnapInAsm = null;
            return foundSnapIn;

        }

        private void okButton_Click(object sender, System.EventArgs e)
        {
            try
            {

                if (this.plugInListBox.Items.Count <= 0)
                {
                    MessageBox.Show("No Code Generators were found,\n conider adding the CodeGenerators.dll available under the sample directory", "Info");
                }
                if (this.plugInListBox.SelectedIndex < 0)
                {
                    MessageBox.Show("No Code Generators were selected", "Info");
                }

            }
            catch
            {
                ErrorMessage.Show("Error! Couldnot write the plugin config file", "error");
            }
        }

        private void cancelButton_Click(object sender, System.EventArgs e)
        {


        }
        void CodeGenPluginFormClosing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            try
            {


                foreach (DataTable table in this.codeGenDataSet.Tables)
                    foreach (DataColumn col in table.Columns)
                        col.ColumnMapping = MappingType.Element;
                this.codeGenDataSet.WriteXml(dpatoolkit.GlobalSettings.CodeGenConfigFile);
            }
            catch
            {
                ErrorMessage.Show("Error! Couldnot write the plugin config file", "error");
            }
        }

    }
}
